
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <iostream>
#include <functional>
#include <string>

using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;

/*


*/

class ChatSever
{
public:
    ChatSever(EventLoop *loop,
              const InetAddress &listenAddr,
              const string &nameArg)
        : server_(loop, listenAddr, nameArg), loop_(*loop)
    {
        // 给服务器注册连接和断开的回调
        server_.setConnectionCallback(bind(&ChatSever::onConnection, this, _1));

        // 给服务器注册用户读写事件回调
        server_.setMessageCallback(bind(&ChatSever::onMessage, this, _1, _2, _3));

        // 设置服务端线程的数量,1个I/O线程，1个worker线程
        server_.setThreadNum(2);
    }
    // 开启事件循环
    void start()
    {
        server_.start();
    }

private:
    // 专门处理用户的连接和断开
    void onConnection(const TcpConnectionPtr &conn)
    {
        if (conn->connected())
        {
            cout << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << "state:online" << endl;
        }
        else
        {
            cout << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << "state:offline" << endl;
            conn->shutdown(); // close(fd);
            // loop->quit();
        }
    }
    // 专门处理用户的读写事件
    void onMessage(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp time)
    {
        string buf = buffer->retrieveAllAsString();
        cout << " receive data:" << buf << " time: " << time.toString() << endl;
        conn->send(buf);
    }
    TcpServer server_;
    EventLoop &loop_;
};

int main()
{
    EventLoop loop;
    InetAddress addr("127.0.0.1", 6000);
    ChatSever server(&loop, addr, "chat_server");
    server.start(); // listen fd epoll_ctl => epoll
    loop.loop();    // epoll wait 以阻塞的方式等待新用户的连接，已连接用户的读写事件

    return 0;
}